import SimpleAnimate from "../animations/SimpleAnimate";
import FingerGuide from "./FingerGuide";
import App from "../framework/App";

//缩放，抖动，耸肩，摇晃，出现手指
export enum GuideType {
    Zoom, Shake, Shrug, Sway, Finger
}

const { ccclass, property } = cc._decorator;

@ccclass
export default class Guide extends cc.Component {

    type: GuideType = GuideType.Zoom;
    currFinger: cc.Node = null;
    loop: boolean;
    times: number = -999;
    removeByClick: boolean;
    defauleScaleX: number = -999;
    defauleScaleY: number = -999;
    defaultPos: cc.Vec2 = cc.v2(-999, -999);
    defaultAngle: number = -999;

    onLoad() {
        this.node.once(cc.Node.EventType.TOUCH_START, this.onTouch, this);
    }

    onDestroy() {
        if (this.currFinger) {
            this.currFinger.destroy();
        }
    }

    /**
     * @param times 每次闪动次数,默认2
     * @param range 动画幅度,默认 zoomScale=1.2 | shakeOffset=3 | shrugScale=1.05 | swayAngle = 5
     * @param loopInterval 循环间隔，默认5
     * @param removeByClick 点击目标后移除指引，默认true
     * @param fingerPosOffset GuideType.Finger专用
     */
    static startGuide(delay: number = 0, target: cc.Node, type: GuideType, loop: boolean, times: number = 2, range: number = -1, fingerPosOffset: cc.Vec2 = cc.Vec2.ZERO, loopInterval: number = 5, removeByClick: boolean = true) {
        if (!target) {
            return;
        }
        let guide = target.getComponent(Guide);
        if (!guide) {
            guide = target.addComponent(Guide);
        }
        if (guide.type == type && guide.loop == loop) {
            return;//已经在循环，不重复创建
        }
        guide.removeByClick = removeByClick;
        if (type == GuideType.Zoom) {
            guide.defauleScaleX = target.scaleX;
            guide.defauleScaleY = target.scaleY;
            let zoomScale = 1.2;
            if (range != -1) {
                zoomScale = range;
            }
            if (loop) {
                guide.schedule(() => {
                    SimpleAnimate.zoomTip(0, guide.node, times, zoomScale);
                }, loopInterval, cc.macro.REPEAT_FOREVER, delay);
            } else {
                SimpleAnimate.zoomTip(delay, guide.node, times, zoomScale, () => { guide.destroy() });
            }
        } else if (type == GuideType.Shake) {
            guide.defaultPos = target.position;
            let shakeOffset = 3;
            if (range != -1) {
                shakeOffset = range;
            }
            if (loop) {
                guide.schedule(() => {
                    SimpleAnimate.shake(0, guide.node, 1, shakeOffset);
                }, loopInterval, cc.macro.REPEAT_FOREVER, delay);
            } else {
                SimpleAnimate.shake(delay, guide.node, 1, shakeOffset, () => { guide.destroy() });
            }
        } else if (type == GuideType.Shrug) {
            guide.defauleScaleX = target.scaleX;
            guide.defauleScaleY = target.scaleY;
            let shrugScale = 1.05;
            if (range != -1) {
                shrugScale = range;
            }
            if (loop) {
                guide.schedule(() => {
                    SimpleAnimate.shrug(0, guide.node, times, shrugScale);
                }, loopInterval, cc.macro.REPEAT_FOREVER, delay);
            } else {
                SimpleAnimate.shrug(delay, guide.node, times, shrugScale, () => { guide.destroy() });
            }
        } else if (type == GuideType.Sway) {
            guide.defaultAngle = target.angle;
            let swayAngle = 5;
            if (range != -1) {
                swayAngle = range;
            }
            if (loop) {
                guide.schedule(() => {
                    SimpleAnimate.sway(0, guide.node, times, swayAngle);
                }, loopInterval, cc.macro.REPEAT_FOREVER, delay);
            } else {
                SimpleAnimate.sway(delay, guide.node, times, swayAngle, true, () => { guide.destroy() });
            }
        } else if (type == GuideType.Finger) {
            guide.scheduleOnce(() => {
                let worldPos = guide.node.convertToWorldSpaceAR(cc.Vec2.ZERO);
                let posInCanvas = cc.Canvas.instance.node.convertToNodeSpaceAR(worldPos);
                posInCanvas.x += fingerPosOffset.x;
                posInCanvas.y += fingerPosOffset.y;
                guide.currFinger = cc.instantiate(App.instance.resPreloader.getRes('prefabs/common/FingerGuide') as cc.Prefab);
                cc.Canvas.instance.node.addChild(guide.currFinger);
                guide.currFinger.position = posInCanvas;
                guide.hideBySeconds(loopInterval);
            }, delay);
        }
        guide.type = type;
        guide.loop = loop;
        guide.times = times;
    }

    static stopGuide(target: cc.Node) {
        if (target) {
            let guide = target.getComponent(Guide);
            if (guide) {
                if (guide.defauleScaleX != -999) {
                    target.scaleX = guide.defauleScaleX;
                }
                if (guide.defauleScaleY != -999) {
                    target.scaleY = guide.defauleScaleY;
                }
                if (cc.v2(-999, -999).sub(guide.defaultPos).mag() > 10) {
                    target.position = guide.defaultPos;
                }
                if (guide.defaultAngle != -999) {
                    target.angle = guide.defaultAngle;
                }
                guide.destroy();
            }
        }
    }

    hideBySeconds(loopInterval: number) {
        this.scheduleOnce(() => {
            if (!this.loop) {
                this.currFinger.getComponent(FingerGuide).fadeOutAndDestroy(() => {
                    this.destroy();
                });
                return;
            }
            this.currFinger.active = false;
            this.scheduleOnce(() => {
                this.currFinger.active = true;
                this.hideBySeconds(loopInterval);
            }, loopInterval);
        }, 2);
    }

    onTouch() {
        if (this.removeByClick) {
            this.destroy();
        }
    }
}
